import axios from "axios";
import { MessageBox, Message } from "element-ui";
import store from "@/store";
import router from "@/router";
import { getToken } from "./auth";
import getErrorMessage from "./expectionalError";

class httpRequest {
  // 实例属性
  sucCode = 0; // 请求成功code
  hideMsgCode = [401, 404];
  // 实例方法
  constructor() {
    this.service = axios.create({
      baseURL: process.env.VUE_APP_BASE_API,
      // baseURL: process.env.VUE_APP_BASE_URL,
      // withCredentials: true, // 跨域请求时允许发送cookie
      timeout: 2 * 60 * 1000,
    });
    // 请求拦截
    this.service.interceptors.request.use(
      (config) => {
        // // 添加请求
        // config.cancelToken = new axios.CancelToken((cancel) => {
        //   store.commit('axios/PUSH_TOKEN', {
        //     cancelToken: cancel
        //   })
        // })
        // token 设置到请求头
        if (getToken()) {
          config.headers.common["Authorization"] = getToken();
          // config.headers['X-Token'] = getToken()
        }
        return config;
      },
      (error) => Promise.reject(error)
    );
    // 响应拦截
    this.service.interceptors.response.use(
      (response) => {
        let data = response.data || {};
        // 返回数据正常 始终以业务错误码为准
        this._formatResponseData(data, ["error_code", "errMsg"]);

        // if (data.errCode !== this.sucCode) {
        //   //#region 其他错误提示统一格式化
        //   const isObj =
        //     Object.prototype.toString.call(data) === "[object Object]";
        //   // 数据为对象时 只取第一项做错误提示
        //   if (isObj) data.errMsg = `${Object.values(data)[0]}`;
        //   const { description } = getErrorMessage(data);
        //   Message.error(description);
        //   //#endregion
        //   return Promise.reject(data);
        // }
        return data;
      },
      (error) => {
        console.log("报错")
        if (!error.response) return Promise.reject(error);
        const { status: statusCode, data: statusData } = error.response || {};
        let {
          error_code: errCode,
          msg: errMsg,
          data: errData,
        } = statusData || {};

        if (statusCode === 401 && errCode === 10040) {
          store.dispatch("user/resetToken");
          router.push("/login");
          Message({
            message: "登录状态已失效，请重新登录",
            type: "warning",
          });
        }
        if (statusCode === 422 && errCode === 10050) {
          store.dispatch("user/resetToken");
          router.push("/login");
          Message({
            message: "登录状态已失效，请重新登录",
            type: "warning",
          });
          return Promise.reject(error);
        }
        
        //#region 其他错误提示统一格式化
        const isObj =
          Object.prototype.toString.call(errData) === "[object Object]";
        // 数据为对象时 只取第一项做错误提示
        if (isObj)
          errMsg = `${Object.keys(errData)[0]} 》${Object.values(errData)[0]}`;
        const { description } = getErrorMessage({
          statusCode,
          errCode,
          errMsg,
        });
        if (error.config && error.config.hide)
          return Promise.resolve(statusData);
        if (!this.hideMsgCode.includes(statusCode)) {
          Message.error(description);
        }
        //#endregion
        return Promise.reject(error);
      }
    );
  }
  // 原型方法
  request(axiosConfig) {
    return this.service(axiosConfig);
  }
  /**
   * 统一 业务数据 键名为 errCode、errMsg
   * @param {Object} data 业务数据
   * @param {Array} param1 默认接收的键名
   */
  _formatResponseData(data, [errCodeKey, errMsgKey]) {
    if (errCodeKey && !data.hasOwnProperty("errCode"))
      // 统一错误码字段名为：errCode
      data["errCode"] = data[errCodeKey];
    if (errMsgKey && !data.hasOwnProperty("errMsg"))
      // 统一错误提示信息为：errMsg
      data["errMsg"] = data[errMsgKey];
    [errCodeKey, errMsgKey].map((v) => delete data[v]); // 移除旧属性
  }
}

export default httpRequest;
